using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Skill_SwordThrow : Skill_Base
{
    private float currentThrowPower;
    private SkillObject_Sword currentSword;

    [Header("----- SwordRegular Throw Details -----")]
    [SerializeField] private GameObject swordRegularPrefab;
    [Range(0, 100)][SerializeField] private float regularThrowPower = 60f;

    [Header("----- SwordPierce Throw Details -----")]
    [SerializeField] private GameObject swordPiercePrefab;
    [Range(0, 100)][SerializeField] private float pierceThrowPower = 60f;
    public int pierceCount = 2;
    private float swordGravityScale = 3.5f;

    [Header("----- SwordSpin Throw Details -----")]
    [SerializeField] private GameObject swordSpinPrefab;
    [Range(0, 100)][SerializeField] private float spinThrowPower = 60f;
    public float maxDistance;
    public float attackPerInterval;
    public float maxDuration;

    [Header("----- SwordBounce Throw Details")]
    [SerializeField] private GameObject swordBouncePrefab;
    [Range(0, 100)][SerializeField] private float bounceThrowPower = 60f;
    public int bounceCount = 5;
    public float bounceSpeed = 12;

    [Header("----- Trajectory Predict Details -----")]
    [SerializeField] private GameObject predictionDot;
    [SerializeField] private int numberofDots = 20;
    [SerializeField] private float spaceBetweenDots = .05f;
    [SerializeField] private Transform[] trajectoryDots;
    public Vector2 trajectoryDirection;

    protected override void Awake()
    {
        base.Awake();
        trajectoryDots = new Transform[numberofDots];
        CreateAllTrajectoryDots();
        swordGravityScale = swordRegularPrefab.GetComponent<Rigidbody2D>().gravityScale;
    }
    public override bool CanUseSkill()
    {
        currentThrowPower = GetCurrentPower();
        if (currentSword != null)
        {
            currentSword.SetSowrdShouldBack();
            return false;
        }
            
        return base.CanUseSkill();
    }

    #region Trajectory Predict
    //游戏开始时创建点并隐藏
    private void CreateAllTrajectoryDots()
    {
        for (int i = 0; i < numberofDots; i++)
        {
            trajectoryDots[i] = Instantiate(predictionDot, transform.position, Quaternion.identity, transform).transform;
            trajectoryDots[i].gameObject.SetActive(false);
        }
    }
    //设置每个轨迹点的位置
    public void PredictTrajectory(Vector2 direction)
    {
        for (int i = 0; i < numberofDots; i++)
        {
            trajectoryDots[i].position = GetTrajectoryDot(direction, i * spaceBetweenDots);
        }
    }
    private float GetCurrentPower()
    {
        return skillUpgradeType switch
        {
            SkillUpgradeType.SwordThrow => regularThrowPower,
            SkillUpgradeType.SwordThrow_Pierce => pierceThrowPower,
            SkillUpgradeType.SwordThrow_Spin => spinThrowPower,
            SkillUpgradeType.SwordThrow_Bounce => bounceThrowPower,
            _ => 0,
        };
    }
    //计算每个轨迹点的位置
    private Vector2 GetTrajectoryDot(Vector2 direction, float t)
    {
        //根据投掷方向和抛力计算初始速度，方向向量x投掷力度
        Vector2 initialVelocity = direction * currentThrowPower;
        //计算重力在时间t内产生的位移影响，这里用到了物理公式s = 0.5 * g * t²，swordGravityScale用于控制重力加速度值缩放
        Vector2 gravityEffect = 0.5f * Physics2D.gravity * swordGravityScale * (t * t);
        //水平方向：初始速度 × 时间（匀速运动）
        //垂直方向：加上重力产生的位移（加速运动）
        //合成为该时间点相对于玩家的位置偏移
        Vector2 predictedPoint = (initialVelocity * t) + gravityEffect;
        Vector2 playerPostion = transform.root.position;
        return playerPostion + predictedPoint;
    }

    #endregion
    public void SwordThrow()
    {
        GameObject swordPrefab = GetSwordPrefab();
        GameObject sword = Instantiate(swordPrefab, trajectoryDots[1].position, Quaternion.identity);
        currentSword = sword.GetComponent<SkillObject_Sword>();
        currentSword.SetupSword(this, GetSwordInitialSpeed());
    }

    private GameObject GetSwordPrefab()
    {
        if (Unlock(SkillUpgradeType.SwordThrow))
            return swordRegularPrefab;
        if (Unlock(SkillUpgradeType.SwordThrow_Pierce))
            return swordPiercePrefab;
        if (Unlock(SkillUpgradeType.SwordThrow_Spin))
            return swordSpinPrefab;
        if (Unlock(SkillUpgradeType.SwordThrow_Bounce))
            return swordBouncePrefab;
        return null;
    }
    public void ConfirmDirection(Vector2 direction) => trajectoryDirection = direction;
    public Vector2 GetSwordInitialSpeed() => trajectoryDirection * currentThrowPower;
    public void EnableDots(bool toggle)
    {
        foreach (var trajectoryDot in trajectoryDots)
            trajectoryDot.gameObject.SetActive(toggle);
    }
}
